Re: SECURITY HOLE: FormMail

Andrew Macpherson (Andrew.Macpherson@bnr.co.uk)
Thu, 3 Aug 1995 22:43:02 +0100

------- =_aaaaaaaaaa0
Content-Type: text/plain; charset="us-ascii"

Paul Phillips wrote:
| Here's the offending line:
|
| open (MAIL, "|$mailprog $FORM{'recipient'}") || die "Can't open $mailprog!\n";

------- =_aaaaaaaaaa0
Content-Type: text/plain; charset="us-ascii"

Just to be helpful, the way to do it more safely, without massive need for
checking is to build a complete mail message, including header, and hand that
to "sendmail -t" which then reads the recipient information out of the
constructed header.  [Sendmail should of course be an invocation of smail or
pp, not the BSD program of that name, given the history of problems that has
had]

... and since I'm sticking my neck out, here's an example script, please rip
to shreds :-)


------- =_aaaaaaaaaa0
Content-Type: text/plain; charset="us-ascii"
Content-Description: booking-form.cgi

#!/usr/bin/perl

print "Content-type: text/htm\r\n\r\n";

if ( $ENV{REQUEST_METHOD} eq "POST") {

$\ = "\r\n";

# It's the POST method, so print content length and coded input from
# STDIN.  Then decode it and print again.

        $len = $ENV{CONTENT_LENGTH};
        $postinput = <STDIN> ;
        $postinput =~ s/\+/ /g ;
        @QUERY_LIST = split( /&/, $postinput);

        foreach $item (@QUERY_LIST) {
                ($param, $value) = split( /=/, $item);
                 $R{$param} = $value;
        }
        foreach $item (sort (keys %R)) {
                $R{$item} =~ s/%([\da-f]{1,2})/pack(C,hex($1))/eig;
                $R{$item} =~ s/\s+$/ /;
                $R{$item} =~ s/^\s+//;
        }
} else {
        print <<"EOX";
Wrong Submission Method

Installation Error

This script accepts input by the POST method. Someone has invoked it with some other method. This means that either you are testing by hand, congratulations, very wise; or that someone has set up a form to call it using some other method. If it was a form, then it was:

$ENV{"HTTP_REFERER"}

EOX exit ; } foreach $musthave ( "MAILTO", "SEMINAR", "NAME", "ADDR1", "ADDR2", "TELNO"){ if ( length($R{ $musthave }) Please tell me more

Insufficient Information

Either
There has been a problem sending your details to this program.
Or
You have not filled in one of the fields I must have to be able to take your booking this way. If this is the case, would you please go back to the form and make sure that you have entered your Name, address, and telephone number, as the very minimum. When you have made these changes, please submit the form again.
EOE exit ; } } $copy = ''; $header = "To: " . $R{"MAILTO"} . "\r\n" . "Sender: nobody\r\nErrors-To: Postmaster@UNCONFIGURED\r\n" . "Subject: " . ( $R{"SEMINAR"} ne '' ? $R{"SEMINAR"} : "WWW On Line booking" ) . "\r\n" ; if ( $R{"EMAIL"} ne '' && $R{"EMAIL"} =~ m/.*@.*/ ) { $em = $R{"EMAIL"}; $header .= "Cc: ${em}\r\nReturn-Receipt-To: ${em}\r\n" ; $copy = "

A copy has also been sent to your e-mail address

" ; } else { $em = $R{"NAME"} . ""; } $header .= "From: ${em}\r\nReply-To: ${em}\r\n\r\n\r\n" ; $body = $R{"SEMINAR"} . "\r\n" . "=================================================================\r\n\r\n" . "Name " . $R{"NAME"} ."\r\n" . "Organisation " . $R{"ORG"} ."\r\n" . "Address " . $R{"ADDR1"} ."\r\n" . " " . $R{"ADDR2"} ."\r\n" . " " . $R{"ADDR3"} ."\r\n" . "Telephone " . $R{"TELNO"} ."\r\n" . "Fax " . $R{"FAXNO"} ."\r\n" . "E-Mail " . $R{"EMAIL"} ."\r\n\r\n" . "=================================================================\r\n\r\n" . "My User Group membership is " . $R{"GROUP"} ."\r\n\r\n" . "Please Register me for the seminar, and invoice me for\r\n" . $R{"BOOKING"} ."\r\n\r\n" . $R{"VEGIE"} ."\r\n\r\n" . "=================================================================\r\n" . $ENV{"HTTP_REFERER"} . "\r\n" . $ENV{"HTTP_USER_AGENT"} . "\r\nFrom " . $ENV{"REMOTE_HOST"} . "(" . $ENV{"REMOTE_ADDR"} . ")\r\n" ; open(MAIL, "|/usr/lib/sendmail -t"); print MAIL $header, $body; close(MAIL); if ( $? == 0 ) { print Form Submitted

Thank You $R{"NAME"}

Your booking form has been submitted

$copy

Here is what was sent

$body
EOF } else { print Request Failed

I'm sorry $R{"NAME"}

We could not submit your registration

Please try again later

EOF } exit ; ------- =_aaaaaaaaaa0 Content-Type: text/plain; charset="us-ascii" -- Andrew.Macpherson.1248566@bnr.co.uk - or - andrew@bnr.ca "Northern Telecom has committed to a 30% reduction in its use of paper by the year 2000." No faxes, or printouts please, just e-mail. ------- =_aaaaaaaaaa0--